﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace Nasa8x.Mvc.Helpers
{


    public interface IPagedList
    {
        int TotalRows
        {
            get;
            set;
        }

        int PageIndex
        {
            get;
            set;
        }

        int PageSize
        {
            get;
            set;
        }

        bool IsPreviousPage
        {
            get;
        }

        bool IsNextPage
        {
            get;
        }
        int PageCount { get; }

    }

    public class PagedList<T> : List<T>, IPagedList
    {
        public PagedList(IQueryable<T> source, int index, int pageSize)
        {
            TotalRows = source.Count();
            PageSize = pageSize;
            PageIndex = index;
            AddRange(source.Skip(index * pageSize).Take(pageSize).ToList());
        }

        public PagedList(List<T> source, int index, int pageSize)
        {
            TotalRows = source.Count();
            PageSize = pageSize;
            PageIndex = index;
            AddRange(source.Skip(index * pageSize).Take(pageSize).ToList());
        }

        public int TotalRows
        {
            get;
            set;
        }

        public int PageIndex
        {
            get;
            set;
        }

        public int PageSize
        {
            get;
            set;
        }

        public bool IsPreviousPage
        {
            get
            {
                return (PageIndex > 0);
            }
        }

        public bool IsNextPage
        {
            get
            {
                return (PageIndex * PageSize) <= TotalRows;
            }
        }

        public int PageCount
        {
            get
            {
                return (int)Math.Ceiling((double)TotalRows / PageSize);


            }
        }
    }




    public static class PagingHelper
    {

        //http://mvcsharp.wordpress.com/2010/02/11/building-a-data-grid-in-asp-net-mvc/


        public static string PageLink(this HtmlHelper html, int currentPage, int totalPages, Func<int, string> pageUrl)
        {

            var diff = 1;
            StringBuilder result = new StringBuilder();
            var TotalPages = totalPages;

            if (currentPage < 1)
                currentPage = 1;

            if ((currentPage + diff) < totalPages)
                totalPages = currentPage + diff;
            var startPage = 1;
            if ((currentPage - diff) > startPage)
                startPage = currentPage - diff;

            if ((currentPage - diff) > 1)
            {
                TagBuilder tag3 = new TagBuilder("a");
                tag3.Attributes.Add("href", pageUrl(1));
                tag3.InnerHtml = "1";
                result.AppendLine(tag3.ToString());
            }

            if ((currentPage - (diff + 1)) > 1)
            {
                TagBuilder tag2 = new TagBuilder("a");
                tag2.Attributes.Add("href", pageUrl(currentPage - (diff + 1)));
                tag2.InnerHtml = "...";
                result.AppendLine(tag2.ToString());
            }

            for (int i = startPage; i <= totalPages; i++)
            {
                TagBuilder tag = new TagBuilder("a");
                tag.Attributes.Add("href", pageUrl(i));
                tag.InnerHtml = i.ToString();
                if (i == currentPage)
                    tag.AddCssClass("pageSelected");
                result.AppendLine(tag.ToString());
            }

            if ((currentPage + (diff + 1)) < TotalPages)
            {
                TagBuilder tag2 = new TagBuilder("a");
                tag2.Attributes.Add("href", pageUrl(currentPage + (diff + 1)));
                tag2.InnerHtml = "...";
                result.AppendLine(tag2.ToString());
            }

            if ((currentPage + diff) < TotalPages)
            {
                TagBuilder tag3 = new TagBuilder("a");
                tag3.Attributes.Add("href", pageUrl(TotalPages));
                tag3.InnerHtml = TotalPages.ToString();
                result.AppendLine(tag3.ToString());
            }
            return result.ToString();
        }



        public static string Paging(this HtmlHelper html, IPagedList pagedList, string pageFormatString)
        {

            StringBuilder sb = new StringBuilder();
            // only show paging if we have more items than the page size
            if (pagedList.TotalRows > pagedList.PageSize)
            {

                sb.Append("<ul class=\"paging\">");

                if (pagedList.IsPreviousPage)
                { // previous link
                    sb.Append("<li class=\"prev\"><a href=\"");
                    //sb.Append(url.Replace(pagePlaceHolder, pagedList.PageIndex.ToString()));
                    sb.AppendFormat(pageFormatString, pagedList.PageIndex);
                    sb.Append("\" title=\"Go to Previous Page\">prev</a></li>");
                }

                for (int i = 0; i < pagedList.PageCount; i++)
                {
                    sb.Append("<li>");
                    if (i == pagedList.PageIndex)
                    {
                        sb.Append("<span>").Append((i + 1).ToString()).Append("</span>");
                    }
                    else
                    {
                        sb.Append("<a href=\"");
                        // sb.Append(url.Replace(pagePlaceHolder, (i + 1).ToString()));
                        sb.AppendFormat(pageFormatString, (i + 1));
                        sb.Append("\" title=\"Go to Page ").Append((i + 1).ToString());
                        sb.Append("\">").Append((i + 1).ToString()).Append("</a>");
                    }
                    sb.Append("</li>");
                }

                if (pagedList.IsNextPage)
                { // next link
                    sb.Append("<li class=\"next\"><a href=\"");
                    //sb.Append(url.Replace(pagePlaceHolder, (pagedList.PageIndex + 2).ToString()));
                    sb.AppendFormat(pageFormatString, pagedList.PageIndex + 2);
                    sb.Append("\" title=\"Go to Next Page\">next</a></li>");
                }

                sb.Append("</ul>");
            }

            return sb.ToString();


        }

        public static string PageRender(this HtmlHelper html, string pageFormatString, int pageIndex, int pageSize, int totalRows)
        {

            var totalPage = (int)Math.Ceiling((double)totalRows / pageSize);

            if (totalPage <= 1) return string.Empty;

            const int pageButtonCount = 3;
            int min = pageIndex - pageButtonCount;
            int max = pageIndex + pageButtonCount;

            if (max > totalPage)
                min -= max - totalPage;
            else if (min < 1)
                max += 1 - min;

            var _sb = new StringBuilder(1000);
            bool needDiv = false;


            _sb.Append("<ul class=\"paging\">");

            //Ren Prev Button
            if (pageIndex > 1)
            {
                _sb.Append("<li class=\"page-prev\"><a href=\"");
                //sb.Append(url.Replace(pagePlaceHolder, pagedList.PageIndex.ToString()));
                _sb.AppendFormat(pageFormatString, pageIndex - 1);
                _sb.Append("\" title=\"Go to Previous Page\">«</a></li>");
            }



            for (int i = 1; i <= totalPage; i++)
            {
                if (i <= 2 || i > totalPage - 2 || (min <= i && i <= max))
                {

                    string _className = (i == pageIndex) ? "page-item-actived" : "page-item";

                    _sb.AppendFormat("<li onclick=\"{0}\" class=\"{1}\"><a href=\"{0}\">{2}</a></li>", string.Format(pageFormatString, i), _className, i);
                    needDiv = true;
                }
                else if (needDiv)
                {
                    _sb.AppendFormat("<li class=\"{0}\">...</li>", "page-item");
                    needDiv = false;
                }
            }

            //Ren Next Button
            if (pageIndex < totalPage)
            {
                _sb.AppendFormat(
                    "<li class=\"{1}\"><a title=\"Go to Next Page\" href=\"{0}\">&#187;</a></li>", string.Format(pageFormatString, pageIndex + 1), "page-next");
            }


            _sb.Append("</ul>");

            return _sb.ToString();


        }


        public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int index, int pageSize)
        {
            return new PagedList<T>(source, index, pageSize);
        }

        public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int index)
        {
            return new PagedList<T>(source, index, 10);
        }

    }
}
